#ifndef NET_SEND_FILTER_H_H
#define NET_SEND_FILTER_H_H

#include <windows.h>
#include <streams.h>
#include <string>
#include <list>

class NetSenderFilter;

class NetSenderReceivePin : public CRenderedInputPin
{
public:
	NetSenderReceivePin(NetSenderFilter* netSenderFilter,HRESULT* hr);
	~NetSenderReceivePin()
	{
		closesocket(m_Socket);
		CloseHandle(m_SendThread);
		TerminateThread(m_SendThread, 1);
	}

	bool start();
	bool stop();
	bool pause();

	bool setSocket(SOCKET socket);
	SOCKET getSocket() const
	{
		return m_Socket;
	}

	bool closeSocket();

	STDMETHODIMP Receive(IMediaSample *pSample);
	STDMETHODIMP EndOfStream();
	STDMETHODIMP BeginFlush();
	STDMETHODIMP EndFlush();
	STDMETHODIMP ReceiveCanBlock();

	HRESULT GetMediaType(int iPosition,CMediaType *pMediaType);
	HRESULT CheckMediaType(const CMediaType *inMediaType);
private:
	SOCKET m_Socket;
	NetSenderFilter* m_NetSenderFilter;
	CCritSec m_CritSec;
	bool m_IsMediaTypeSend;
	bool m_IsStart;
	long long m_SendedSize;

	HANDLE m_SendThread;
	HANDLE m_NewDataSemaphore;
	CCritSec m_NewDataListCric;
	std::list<std::pair<AM_SAMPLE2_PROPERTIES, std::string> > m_NewDataList;
};

class NetSenderFilter : public CBaseFilter
{
	friend class NetSenderReceivePin;
public:
	NetSenderFilter(HRESULT* hr);
	~NetSenderFilter()
	{
		delete m_ReceivePin;
	}

	bool setSocket(SOCKET socket)
	{
		return m_ReceivePin->setSocket(socket);
	}
	bool start()
	{
		return m_ReceivePin->start();
	}
	bool stop()
	{
		return m_ReceivePin->stop();
	}
	bool pause()
	{
		return m_ReceivePin->pause();
	}

	CBasePin* GetPin(int n)
	{
		if(n == 0)
			return m_ReceivePin;
		else
			return NULL;
	}
	int GetPinCount()
	{
		return 1;
	}
	STDMETHODIMP Stop();
	bool closeSocket();
private:
	NetSenderReceivePin* m_ReceivePin;
	CCritSec m_CritSec;
};


#endif